explainText _ 'A SimpleRectThing consists of four points (topLeft, center, bottomRight, and extent) and a mask and rule for filling itself with some pattern. If the mask is nil, only its outline is displayed. A SimpleRectThing has no constraints among its parts.'.! !
explainText _ 'A TrebleClefThing is a staff with built in treble clef. The staff width is determined by the width component while the vertical offset of middle C (from the top of the staff) is given by the middleCOffset component.'.! !
explainText _ 'A RectThing is like a SimpleRectThing but the corners, center, and extent are constrained so that that given any two of these we can compute the others. This generality is expensive, however, so it it best to use one of the more limited varieties of rectangle things (CenterRectThing or FixedRectThing) where appropriate.'.! !
RectThing initialize!
PrimitiveThing subclass: #PointAnchor
instanceVariableNames: 'point '
classVariableNames: 'DisplayForm '
poolDictionaries: ''
category: 'Things-Primitive'!
!PointAnchor methodsFor: 'initialization'!
initializeConstraints
"PointerAnchor initialize"
self stronglyPreferStay: #point.x.
self stronglyPreferStay: #point.y.!
initializeStructure
point _ PointThing cloneFor: self.! !
!PointAnchor methodsFor: 'access'!
point
^point! !
!PointAnchor methodsFor: 'glyphs'!
boundingBox
"Answer a box around my DisplayForm centered on my location."
explainText _ 'A CenterRectThing is a SimpleRectThing with the addition of constraints to keep the center point midway between the origin and corner points and to keep the extent point updated. The extent cannot be changed by any other constraints.'.! !
explainText _ 'A FixedRectThing is a SimpleRectThing with the addition of constraints that use its width and height to compute a corner and the center given the other corner. The center cannot be changed by any other constraints but the extent can.'.! !
FixedRectThing initialize!
PrimitiveThing subclass: #LineThing
instanceVariableNames: 'p1 p2 '
classVariableNames: 'PenForm '
poolDictionaries: ''
category: 'Things-Primitive'!
!LineThing methodsFor: 'initialization'!
initializeStructure
p1 _ PointThing cloneFor: self.
p2 _ PointThing cloneFor: self.!
initializeValues
self set: #p1.x to: 10.
self set: #p1.y to: 10.
self set: #p2.x to: 30.
self set: #p2.y to: 30.! !
!LineThing methodsFor: 'access'!
p1
^p1!
p2
^p2! !
!LineThing methodsFor: 'glyphs'!
boundingBox
"Return the smallest rectangle enclosing both my endpoints."
explainText _ 'A Node is a value holder. It has a location and a value, which can be of any type. It also maintains a history of the last several values it has held.'.
explainText _ 'A ScrollThing consists a node, a box, and a horizonal marker. The vertical position of the marker within the box is proportional to the value of the node within the range [minVal..maxVal].'.! !
VScrollThing initialize!
PrimitiveThing subclass: #NodeAnchor
instanceVariableNames: 'node '
classVariableNames: 'DisplayForm '
poolDictionaries: ''
category: 'Things-Primitive'!
!NodeAnchor methodsFor: 'initialization'!
initializeConstraints
"NodeAnchor initialize"
self stronglyPreferStay: #node.value.!
initializeStructure
node _ Node cloneFor: self.! !
!NodeAnchor methodsFor: 'access'!
location
^node location!
node
^node! !
!NodeAnchor methodsFor: 'glyphs'!
boundingBox
"Answer a box around my DisplayForm centered on my location."
"This constraint computes a force vector for each endpoint. The direction of this vector will be parallel to the rod and either inward at each endpoint (if the rod is stretched longer than its nominal length) or outward at each endpoint (if the rod is compressed)."
explainText _ 'A RodThing is a stretchable, compressible rod of some nominal length that obeys Hooke''s law for springs. I compute the force vector for each of my endpoints (which is zero if I am neither stretched nor compressed).'.! !
explainText _ 'A ThreeWayOp is a template Thing for three operand operators. It is used as a sub-part of other Things, rather than as a stand-alone Thing. It provides three Nodes and an operator Form.'.! !
explainText _ 'A PenRecorderThing records and display the last N values of its input, like an oscilloscope. The vertical scale and offset are adjustable.'.! !
PenRecorderThing initialize!
PrimitiveThing subclass: #BasicTextThing
instanceVariableNames: 'box node '
classVariableNames: ''
poolDictionaries: ''
category: 'Things-Private'!
!BasicTextThing methodsFor: 'initialization'!
initializeStructure
box _ FixedRectThing cloneFor: self.
node _ Node cloneFor: self.!
initializeValues
self set: #box.extent.x to: 30.
self set: #box.extent.y to: 15.
self set: #node.location.x to: 25.
self set: #node.location.y to: 30.
self set: #node.value to: 'Text'.! !
!BasicTextThing methodsFor: 'access'!
box
^box!
displayText
"Answer the text to be displayed. Subclasses may override this behavior."
explainText _ 'A HistorySplitter splits the value of a node into its current and previous values.'.! !
HistorySplitter initialize!
PrimitiveThing subclass: #FormPrinter
instanceVariableNames: 'location node '
classVariableNames: 'BitColor PenForm '
poolDictionaries: ''
category: 'Things-Primitive'!
FormPrinter comment:
'This is a direct copy of NumberPrinter as of 18-Jan-89 modified to handle Forms rather than numbers. The modification and bitEditing code was added by Bjorn Freeman-Benson.
Some changes: the box is autosizing.'!
!FormPrinter methodsFor: 'initialization'!
initializeStructure
location _ PointThing cloneFor: self.
node _ Node cloneFor: self.!
initializeValues
self set: #location.x to: 30.
self set: #location.y to: 20.
self set: #node.location.x to: 60.
self set: #node.location.y to: 60.
self set: #node.value to: (Form extent: 30@20).! !
!FormPrinter methodsFor: 'access'!
location
^location!
node
^node! !
!FormPrinter methodsFor: 'glyphs'!
boundingBox
"Answer a box around my form display box centered on my location."
explainText _ 'A ScrollingListThing consists of a scroll bar, a menu Thing, and nodes to hold the list of menu items (itemsList) and the selected item (selectedItem). It also has several variables that it uses internally such as the visible item count and the index of the first item to display.'.! !
explainText _ 'A BassClefThing is a staff with a built in bass clef. See the comment for TrebleClefThing for further details.'.! !
BassClefThing initialize!
BasicTextThing subclass: #NumberText
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Things-Private'!
!NumberText methodsFor: 'initialization'!
initializeValues
self set: #box.extent.x to: 46.
self set: #box.extent.y to: 15.
self set: #node.location.x to: 33.
self set: #node.location.y to: 28.
self set: #node.value to: 0.! !
!NumberText methodsFor: 'access'!
displayText
"Answer the text to be displayed."
^node value printString! !
!NumberText methodsFor: 'keyboard'!
handleKeystroke: aCharacter view: aView
"Accept the given character. If it is a digit, update myself. If it is backspace, delete my last digit, if any. If it is a minus sign, change my sign."
| value valueString |
value _ node value.
valueString _ node value printString.
(value respondsTo: #even) ifFalse:
[value _ 0. valueString _ '0']. "if value isn't a number, make it zero"
explainText _ 'A NumberText is like a BasicTextThing except that it parses numbers on keyboard entry and stores the resulting numeric value in its node rather than the string itself.'.! !
explainText _ 'A NumberPrinter is a numeric value holder that prints its contents in a box. The value may be edited by typing digits, backspaces, the decimal point, and/or the minus sign while the NumberPrinter is selected.'.! !
explainText _ 'An OrbitThing consists of two Points, a center and a satellite. It also has two NumberTexts for specifying the orbit radius and rate (the rate specifies how many degrees to increment theta each iteration).'.! !
explainText _ 'A NumberDisplayer consists of a fixed-size box for displaying the number plus a node to hold the number. The relative locations of the node and display box are fixed by constraints. A NumberDisplayer accepts the keyboard input of numbers just like a NumberPrinter.'.! !
NumberDisplayer initialize!
PrimitiveThing subclass: #Incrementor
instanceVariableNames: 'node '
classVariableNames: 'DisplayForm '
poolDictionaries: ''
category: 'Things-Primitive'!
!Incrementor methodsFor: 'initialization'!
initializeConstraints
"Incrementor initialize"
self stronglyPreferEdit: #node.last.
self methods: #('current _ last + 1')
where: #((current node.value) (last node.last))
strength: #strongPreferred.!
initializeStructure
node _ Node cloneFor: self.!
initializeValues
self set: #node.location.x to: 25.
self set: #node.location.y to: 20.
self set: #node.last to: -1.! !
!Incrementor methodsFor: 'access'!
location
^node location!
node
^node! !
!Incrementor methodsFor: 'glyphs'!
boundingBox
"Answer a box around my DisplayForm centered on my location."
explainText _ 'A TwoWayOp is a template for two operand operators. It is used as a sub-part of other Things, rather than as a stand-alone Thing. It provides two Nodes and an operator Form.'.! !
TwoWayOp initialize!
PrimitiveThing subclass: #Invert
instanceVariableNames: 'op '
classVariableNames: ''
poolDictionaries: ''
category: 'Things-Primitive'!
Invert comment:
'This Thing is a copy of Sum as of 18-Jan-89 modified to handle Forms. This Thing inverts the bitmap as it goes through.'!